package top.lisicheng.controller;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import top.lisicheng.model.CommonResult;
import top.lisicheng.model.Payment;
import top.lisicheng.service.PaymentService;

import javax.annotation.Resource;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author Lisicheng
 */
@RequestMapping("payment")
@RestController
@Slf4j
public class PaymentController {

    @Resource
    private PaymentService paymentService;

    @RequestMapping("get")
    public CommonResult get(Long id) {
        log.info("查询：id：" + id);
        return new CommonResult<>(200, "成功8001");
    }

    @RequestMapping("timeout")
    @HystrixCommand(fallbackMethod = "timeoutHandler", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
    })
    public CommonResult timeout() {

        // 发送异常，也会触发降级
        // int a = 10 / 0;

        // 超过设置的接受等待时长，也会触发降级
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return new CommonResult(200, "休眠3s");
    }

    public CommonResult timeoutHandler() {
        return new CommonResult(200, "服务繁忙，请稍后等待");
    }

    /* 服务熔断 */
    @HystrixCommand(fallbackMethod = "fushFallback", commandProperties = {
            @HystrixProperty(name = "circuitBreaker.enabled", value = "true"), // 是否开启熔断器
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),// 请求次数
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), // 时间周期（毫秒）
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"), // 失败率
            // 在时间周期内，请求失败次数达到失败率，触发熔断
    })
    @GetMapping("fush")
    public CommonResult fush(@RequestParam("id") Long id) {

        if (id < 0) {
            throw new RuntimeException();
        }

        return new CommonResult(200, "成功，" + UUID.randomUUID());
    }

    public CommonResult fushFallback(@RequestParam("id") Long id) {
        return new CommonResult(500, "id不能为负数：" + id);
    }
}
